package com.cainiao.stock.service.Impl;

import cn.hutool.core.util.StrUtil;
import com.cainiao.stock.config.DtpConfiguration;
import com.cainiao.stock.config.ThreadPoolExecutorConfiguration;
import com.cainiao.stock.entity.StockBlockRtInfo;
import com.cainiao.stock.entity.StockBusiness;
import com.cainiao.stock.entity.StockMarketIndexInfo;
import com.cainiao.stock.mapper.StockBlockRtInfoMapper;
import com.cainiao.stock.mapper.StockBusinessMapper;
import com.cainiao.stock.mapper.StockMarketIndexInfoMapper;
import com.cainiao.stock.properties.MarketProperties;
import com.cainiao.stock.service.StockTimerTaskService;
import com.cainiao.stock.util.IdWorkers;
import com.cainiao.stock.util.ParserStockInfoUtil;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.dromara.dynamictp.core.executor.DtpExecutor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;
import com.alibaba.fastjson2.JSON;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.regex.Matcher;
import java.util.regex.Pattern;



@Slf4j
@Service
public class StockTimerTaskServiceImpl implements StockTimerTaskService {
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private MarketProperties properties;
    @Autowired
    private IdWorkers idWorker;
    @Autowired
    private StockMarketIndexInfoMapper stockMarketIndexInfoMapper;
    @Autowired
    private StockBusinessMapper stockBusinessMapper;
    @Autowired
//    private ThreadPoolExecutor threadPoolExecutor;
    private DtpExecutor dtpExecutor;
    //注入格式解析bean
    @Autowired
    private ParserStockInfoUtil parserStockInfoUtil;
    @Autowired
    private StockBlockRtInfoMapper stockBlockRtInfoMapper;

    @Override
    public void getInnerMarketInfo() {

        String urlPrefix = "https://hq.sinajs.cn/list=";
        List<String> inner = properties.getInner();
        StringJoiner stringJoiner=new StringJoiner(",");
        inner.forEach(
                s -> stringJoiner.add(s)
        );
        String url=urlPrefix+stringJoiner;
        HttpMethod method=HttpMethod.GET;
        HttpHeaders headers=new HttpHeaders();
        headers.add("Referer","https://finance.sina.com.cn/stock/");
        headers.add("User-Agent","Mozilla/5.0 (Windows NT 10.0; WOW64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36");
        HttpEntity<?> entity=new HttpEntity<>(headers);
        ResponseEntity<String> exchange = restTemplate.exchange(url, method, entity, String.class);
        String body = exchange.getBody();
        String reg="var hq_str_(.+)=\"(.+)\";";
        Pattern pattern=Pattern.compile(reg);
        Matcher matcher=pattern.matcher(body);
        List<StockMarketIndexInfo> list= Lists.newArrayList();
        while (matcher.find()){
            //获取大盘的id
            String marketCode = matcher.group(1);
            System.out.println(marketCode);
            //其它信息
            String other = matcher.group(2);
            String[] others = other.split(",");
            //大盘名称
            String marketName=others[0];
            //当前点
            BigDecimal curPoint=new BigDecimal(others[1]);
            //当前价格
            BigDecimal curPrice=new BigDecimal(others[2]);
            //涨跌率
            BigDecimal upDownRate=new BigDecimal(others[3]);
            //成交量
            Long tradeAmount=Long.valueOf(others[4]);
            //成交金额
            Long tradeVol=Long.valueOf(others[5]);
            //当前日期
            //封装对象
            StockMarketIndexInfo stockMarketIndexInfo = StockMarketIndexInfo.builder()
                    .id(idWorker.nextId()+"")
                    .markName(marketName)
                    .curTime(LocalDateTime.now())
                    .tradeVolume(tradeVol)
                    .tradeAccount(tradeAmount)
                    .updownRate(upDownRate)
                    .curPoint(curPoint)
                    .currentPrice(curPrice)
                    .markId(marketCode)
                    .build();
            list.add(stockMarketIndexInfo);
        }
        dtpExecutor.execute(()->{
            stockMarketIndexInfoMapper.insertBatch(list);
        });

    }

    /**
     * 批量获取股票每分钟的数据详情信息
     * http://hq.sinajs.cn/list=sz000002,sh600015
     */
    @Override
    public void getStockRtIndex() {

        //批量获取股票ID集合
        List<StockBusiness> stockIds = stockBusinessMapper.selectAll();
        List<String> lists = stockIds.stream().map(ids -> {
            if(StrUtil.startWith(ids.getSecCode().substring(3),"600")||
                    StrUtil.startWith(ids.getSecCode().substring(3),"601")||
                    StrUtil.startWith(ids.getSecCode().substring(3),"603")){
                return "sh" + ids;
            }else if (StrUtil.startWith(ids.getSecCode().substring(3),"000")) {
                return "sz" + ids;
            }
            return null;
        }).toList();
        //设置公共请求头对象
        String join=String.join(",",lists);
//        String url=String.join()
        //设置请求头数据
        HttpHeaders headers = new HttpHeaders();
        headers.add("Referer","https://finance.sina.com.cn/stock/");
        headers.add("User-Agent","Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36");
        HttpEntity<String> entity = new HttpEntity<>(headers);
        Lists.partition(stockIds,20).forEach(list->{
//            //拼接股票url地址
//            String stockUrl="http://hq.sinajs.cn/list="+String.join(",",list);
//            //获取响应数据
//            String result = restTemplate.postForObject(stockUrl,entity,String.class);
//            List<StockRtInfo> infos = parserStockInfoUtil.parser4StockOrMarketInfo(result, 3);
//            log.info("数据量：{}",infos.size());
        });
        //todo
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void getStockBlockInfo() {
        String url = "http://vip.stock.finance.sina.com.cn/q/view/newSinaHy.php";
        HttpMethod method = HttpMethod.GET;
        HttpHeaders headers = new HttpHeaders();
        headers.add("Referer", "https://finance.sina.com.cn");
        headers.add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36");
        HttpEntity<?> entity = new HttpEntity<>(headers);
        ResponseEntity<String> response = restTemplate.exchange(url, method, entity, String.class);
        String body = response.getBody();
        String regex = "var S_Finance_bankuai_sinaindustry =(.+)";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(body);
        List<StockBlockRtInfo> blockRtInfos = new ArrayList<>();
        while (matcher.find()) {
            String jsonStr = matcher.group(1);
            Map map = JSON.parseObject(jsonStr, Map.class);
            System.out.println(map);
            Collection values = map.values();
            for (Object valueStr : values) {
                String value = valueStr.toString();
                String[] split = value.split(",");
                String label = split[0];
                String block_name = split[1];
                String company_num_str = split[2];
                Integer company_num = Integer.valueOf(company_num_str);
                String avg_price_str = split[3];
                BigDecimal avg_price = new BigDecimal(avg_price_str);
                String updown_rate_str = split[5];
                BigDecimal updowm_rate = new BigDecimal(updown_rate_str);
                String trade_amount_str = split[6];
                Long trade_amount = Long.parseLong(trade_amount_str);
                String trade_volume_str = split[7];
                BigDecimal trade_volume = new BigDecimal(trade_volume_str);

                StockBlockRtInfo stockBlockRtInfo = StockBlockRtInfo.builder()
                        .id(idWorker.nextStrId())
                        .label(label)
                        .blockName(block_name)
                        .companyNum(company_num)
                        .avgPrice(avg_price)
                        .updownRate(updowm_rate)
                        .tradeAmount(trade_amount)
                        .tradeVolume(trade_volume)
                        .curTime(LocalDateTime.now())
                        .build();
                blockRtInfos.add(stockBlockRtInfo);
            }
        }

        stockBlockRtInfoMapper.save(blockRtInfos);
    }
}
